package com.rt.tmpt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.inspiresoftware.lib.dto.geda.annotations.Dto;
import com.inspiresoftware.lib.dto.geda.assembler.DTOAssembler;
import com.inspiresoftware.lib.dto.geda.exception.AnnotationMissingAutobindingException;
import com.inspiresoftware.lib.dto.geda.exception.AutobindingClassNotFoundException;
import com.rt.code.generator.freemarker.exec.FmUtils;
import com.rt.easyjava.base.biz1.mapper.TmptUserSettingMapper;
import com.rt.easyjava.common.utils.others.DateUtils;
import com.rt.tmpt.bean.*;
import com.rt.tmpt.dao.intf.*;
import com.rt.tmpt.dto.A1OperationlogDto;
import com.rt.tmpt.dto.A2UserDto;
import com.rt.tmpt.dto.A3MenuDto;
import com.rt.tmpt.dto.Result;
import com.rt.tmpt.service.IMenuService;
import com.rt.tmpt.service.IOperationlogService;
import com.rt.tmpt.utils.DateTool;
import com.rt.tmpt.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.hibernate.Session;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(propagation = Propagation.REQUIRED)
@Slf4j
public class MenuService implements IMenuService {

    @Resource
    IA3MenuDao a3MenuDao;
    @Resource
    IA3MenuMyDao a3MenuMyDao;
    @Resource
    IA2RoleDao a2RoleDao;
    @Resource
    IA2UserDao a2UserDao;
    @Resource
    IOperationlogService operationlogService;
    @Resource
    IA1TemplateTableDao a1TemplateTableDao;
    @Resource
    IA1TemplateColumnDao a1TemplateColumnDao;

    @PersistenceContext
    private EntityManager entityManager;

    private Session getCurrentSession() {
        Session session = (Session) entityManager.getDelegate();
        return session;
    }


    @Override
    public Result bindAuths2Role(long roleId, String[] menuIdArr, Map dataLimitTypeMap, A1OperationlogDto logDto) {
        Result result = new Result();
        A2Role a2Role = a2RoleDao.findById(roleId).get();

        //角色下已存在菜单，先删除这些菜单
        List<A3MenuMy> menuMyList = new ArrayList<>();
        int count = 0;
        for (A3MenuMy menuMy : a2Role.getA3MenuMyList()) {
            menuMyList.add(menuMy);
            if (++count % 1000 == 0) {
                a3MenuMyDao.deleteInBatch(menuMyList);
                menuMyList.clear();
            }
        }
        if (menuMyList.size() > 0) {
            a3MenuMyDao.deleteInBatch(menuMyList);
        }
		/*if(a2Role.getA3MenuMyList().size()>0){
			a3MenuMyDao.deleteInBatch(a2Role.getA3MenuMyList());
		} */

        List<A3MenuMy> a3MenuMyList = new ArrayList<>();
        for (int i = 0; i < menuIdArr.length; i++) {
            Long menuId = Long.parseLong(menuIdArr[i]);
            // data limit type
            Object dataLimitTypeObj = dataLimitTypeMap.get("d_" + menuId);
            int dataLimitTypeInt = 0;
            if (dataLimitTypeObj != null) {
                dataLimitTypeInt = Integer.parseInt(dataLimitTypeObj.toString());
            }

            Optional<A3Menu> optionalA3Menu = a3MenuDao.findById(menuId);
            A3Menu a3Menu = optionalA3Menu.get();
            A3MenuMy menuMy = new A3MenuMy().setDefaultValues();
            menuMy.setA2Role(a2Role);
            menuMy.setA3Menu(a3Menu);
            menuMy.setDataLimitType(dataLimitTypeInt);
            a3MenuMyList.add(menuMy);
        }
        a3MenuMyDao.saveAll(a3MenuMyList);

        //日志
        if (logDto != null) {
            logDto.setLogTypeName("后台：员工管理");
            logDto.setDescription("绑定角色 和 菜单：roleId:" + roleId);
            operationlogService.addOperationlog(logDto);
        }
        return result.success();
    }


    @Override
    public Result addMenu(A3MenuDto menuDto, long parentId) {
        Result result = new Result();

        A3Menu menu = new A3Menu();
        DTOAssembler dtoAssembler = DTOAssembler.newAssembler(A3MenuDto.class);
        dtoAssembler.assembleEntity(menuDto, menu, null, null);

        //找上级
        A3Menu parentMenu = null;
        if (parentId != 0) {
            parentMenu = a3MenuDao.findById(parentId).get();
        }
        //添加数据
        menu.setA3MenuParent(parentMenu);
        a3MenuDao.save(menu);
        result.setObj(menu);

        return result.success();
    }

    @Override
    public Result<A3MenuDto> queryMenuById(long id) {
        Result<A3MenuDto> result = new Result();

        A3Menu menu = a3MenuDao.findById(id).get();
        A3MenuDto menuDto = new A3MenuDto();
        DTOAssembler dtoAssembler = DTOAssembler.newAssembler(A3MenuDto.class);
        dtoAssembler.assembleDto(menuDto, menu, null, null);
        result.setObj(menuDto);

        return result.success();
    }

    @Override
    public Result<A3MenuDto> modifyMenuById(A3MenuDto menuDto) {
        String auths = menuDto.getAuth(); // 有重复项，去重。 a:query;b:query;a:query;
        String authString = "";
        if (!StringUtils.isNull(auths)) {
            auths = auths.replaceAll("\n", "");
            List<String> _authList = Arrays.asList(auths.split(";"));
            List<String> authList = _authList.stream().distinct().collect(Collectors.toList()); //去重
            Collections.sort(authList, new Comparator<String>() {  //排序
                @Override
                public int compare(String o1, String o2) {
                    return o1.compareTo(o2);
                }
            });

            StringBuilder sb = new StringBuilder();
            for (String auth : authList) {
                sb.append(auth).append(";\n");
            }
            authString = sb.toString();
        }


        Result<A3MenuDto> result = new Result();
        A3Menu menu = a3MenuDao.findById(menuDto.getId()).get();
        menu.setText(menuDto.getText());
        menu.setSort(menuDto.getSort());
        menu.setNameEn(menuDto.getNameEn());
        menu.setUrl(menuDto.getUrl());
        menu.setAuth(authString);
        menu.setType(menuDto.getType());
        menu.setKeyRandom(menuDto.getKeyRandom());
        menu.setHasDataLimit(menuDto.getHasDataLimit());
        menu.setIconClass(menuDto.getIconClass());
        menu.setSort(menuDto.getSort());
        a3MenuDao.save(menu);

        return result.success();
    }

    public static void main(String[] args) {
        String auths = "a1;b2;a2;b3";
        List<String> _authList = Arrays.asList(auths.split(";"));
        Collections.sort(_authList, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println(_authList);
    }

    @Override
    public Result<A3MenuDto> batchUpdateMenusSort(List<A3MenuDto> a3MenuDtoList) {
        Result<A3MenuDto> result = new Result();

        for (A3MenuDto menuDto : a3MenuDtoList) {
            A3Menu menu = a3MenuDao.findById(menuDto.getId()).get();
            menu.setSort(menuDto.getSort());
            A3Menu menuParent = null;
            if (menuDto.getMenuParentId() != null && menuDto.getMenuParentId().intValue() != 0) {
                menuParent = a3MenuDao.findById(menuDto.getMenuParentId()).get();
            }
            menu.setA3MenuParent(menuParent);
            a3MenuDao.save(menu);
        }

        return result.success();
    }

    /**
     * batch create menuMap as childen under pId tree node
     *
     * @param pIdInt
     * @param menuMap
     * @return
     */
    @Override
    public Result<A3MenuDto> publishMenu(Integer pIdInt, Map<String, Object> menuMap, Long userId) {
        Result<A3MenuDto> result = new Result();
        Long pId = Long.parseLong(String.valueOf(pIdInt));
        // reduce
        createMenuReduce(pId, menuMap, userId);
        return result.success();
    }

    private void createMenuReduce(Long pId, Map<String, Object> menuMap, Long userId) {
        // 找上级 : current node , as parent node for menuMap
        A3Menu menuParent = null;
        if (pId != 0) {
            menuParent = a3MenuDao.findById(pId).get();
        }
        String name = (String) menuMap.get("name");
        String nameEn = (String) menuMap.get("nameEn");
        String url = (String) menuMap.get("url");
        String auth = (String) menuMap.get("auth");
        Integer sort = (Integer) menuMap.get("sort");
        Integer type = (Integer) menuMap.get("type");
        Integer hasDataLimit = (Integer) menuMap.get("hasDataLimit");
        A3Menu menu = new A3Menu();
        menu.setText(name);
        menu.setNameEn(nameEn);
        menu.setUrl(url);
        menu.setAuth(auth);
        menu.setSort(sort);
        menu.setType(type);
        menu.setHasDataLimit(hasDataLimit);
        menu.setA3MenuParent(menuParent);
        menu.setDeleteFlag(0);
        menu.setCompanyId(userId);
        menu.setCreatemanId(0L);
        menu.setModifymanId(0L);
        menu.setCreateDate(DateTool.getCurTimestamp());
        // save current menu
        menu = a3MenuDao.save(menu);
        Long curId = menu.getId();

        // children
        List<Map> menuChildren = (List<Map>) menuMap.get("children");
        if (menuChildren == null || menuChildren.size() == 0) {
            return;
        }
        for (Map map : menuChildren) {
            // reduce myself
            createMenuReduce(curId, map, userId);
        }
    }

    @Override
    public Result<A3MenuDto> removeMenuById(long id) {
        Result<A3MenuDto> result = new Result();

        A3Menu menu = a3MenuDao.findById(id).get();
        menu.setDeleteFlag(1);
        a3MenuDao.save(menu);

        return result.success();
    }

    /**
     * 删除菜单节点，接联删除
     *
     * @param id
     * @return
     */
    @Override
    public Result<A3MenuDto> removeMenu4AllNodesById(long id) {
        Result<A3MenuDto> result = new Result();

        A3Menu menu = a3MenuDao.findById(id).get();
        removeMenuReduce(menu);

        return result.success();
    }

    private void removeMenuReduce(A3Menu menu) {
        menu.setDeleteFlag(1);
        a3MenuDao.save(menu);
        //
        List<A3Menu> menuList = menu.getA3MenuSonList();
        if (menuList == null || menuList.size() == 0) {
            return;
        }
        //reduce
        for (A3Menu menu1 : menuList) {
            removeMenuReduce(menu1);
        }
    }


    /**
     * Vue
     * 查询菜单tree结构
     *
     * @param paramMap :menuType menuType的最小级（0=menu; 10=leave menu; 20=function 30=function url）；如传入20，则递归查询type<=20
     * @return
     */
    @Override
    public Result<A3MenuDto> queryMenus4RoleConf(Map<String, Object> paramMap) {
        // 表示哪个menuId作为第1级树。 空：表示从顶开始查
        String id = (String) paramMap.get("id");
        //MenuFromRoleMag 权限分配: 在权限分配页面希望子节点是"查询"这一级别
        //MenuMag 菜单管理
        String from = (String) paramMap.get("from");
        Result<A3MenuDto> result = new Result();

        System.out.println("t1:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));
        List<A3Menu> menuList = null;
        if (StringUtils.isNull(id) || "0".equalsIgnoreCase(id)) {
            //查询顶级菜单
            menuList = a3MenuDao.findByA3MenuParentIsNullAndDeleteFlagOrderBySort(0);
        } else {
            A3Menu a3Menu = new A3Menu();
            A3Menu a3MenuP = new A3Menu();
            a3MenuP.setId(Long.parseLong(id));
            a3Menu.setA3MenuParent(a3MenuP);
            a3Menu.setDeleteFlag(0);
            Sort sort = Sort.by(Sort.Direction.ASC, "sort");
            menuList = a3MenuDao.findAll(Example.of(a3Menu), sort);
        }
        System.out.println("t2:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));

        //递归生成树，存储在jsonObject里
        JSONObject jsonObject = new JSONObject();
        genMenuJsonTree(jsonObject, menuList, from);
        JSONArray jsonArray = jsonObject.getJSONArray("children");
        List list = jsonArray.toList();
        //String menuJson = jsonArray.toString();
        System.out.println("t3:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));

        //result.getMap().put("menuJson", menuJson);
        System.out.println("list:" + list);
        result.getMap().put("list", list);
        return result.success();
    }

    /**
     * 递归Post生成树
     */
    private void genMenuJsonTree(JSONObject jsonObject, List<A3Menu> menuList, String from) {
        //System.out.println("-=====>from:" + from);
        JSONArray jsonArray = new JSONArray();
        jsonObject.put("children", jsonArray);

        for (A3Menu menu : menuList) {
            int deleteFlag = menu.getDeleteFlag();
            if (deleteFlag == 1) {
                continue;
            }
            long id = menu.getId();
            long menuParentId = menu.getA3MenuParentId() == null ? 0 : menu.getA3MenuParentId().longValue();
            String text = menu.getText();
            String url = menu.getUrl();
            String auth = menu.getAuth();
            int type = menu.getType()==null?0:menu.getType().intValue();
            int hasDataLimit = menu.getHasDataLimit()==null?0:menu.getHasDataLimit().intValue();
            String iconClass = menu.getIconClass();
            int sort = menu.getSort()==null?0:menu.getSort().intValue();
            String keyRandom = menu.getKeyRandom() == null ? "" : menu.getKeyRandom();
            String nameEn = menu.getNameEn() == null ? "" : menu.getNameEn();

            //json
            JSONObject jsonObjectSon = new JSONObject();
            jsonObjectSon.put("id", id);
            jsonObjectSon.put("menuParentId", menuParentId);
            jsonObjectSon.put("label", text);
            jsonObjectSon.put("name", text);
            jsonObjectSon.put("nameEn", nameEn);
            jsonObjectSon.put("auth", auth == null ? "" : auth);
            jsonObjectSon.put("url", url == null ? "" : url);
            jsonObjectSon.put("type", type);
            jsonObjectSon.put("hasDataLimit", hasDataLimit);
            jsonObjectSon.put("iconClass", iconClass);
            jsonObjectSon.put("sort", sort);
            jsonObjectSon.put("keyRandom", keyRandom);
            if ("MenuMag".equals(from)) {
                if (type == 20) {
                    jsonObjectSon.put("state", "closed");
                } else {
                    jsonObjectSon.put("state", "closed");
                }
            }


            //菜单上的属性
            JSONObject joAttr = new JSONObject();
            //joAttr.put("checkState", "true");
            joAttr.put("type", type);
            joAttr.put("url", url == null ? "" : url);
            joAttr.put("hasDataLimit", hasDataLimit);
            jsonObjectSon.put("attributes", joAttr);
            jsonArray.put(jsonObjectSon);

            if ("MenuFromRoleMag".equals(from)) {
                if (type >= 20) {
                    continue;
                }
            }
            if ("MenuMag".equals(from)) {
                if (type >= 30) {
                    continue;
                }
            }
            //只显示1级菜单
            if ("OneLevel".equals(from)) {
                if (type >= 0) {
                    continue;
                }
            }

            List<A3Menu> menuSonList = menu.getA3MenuSonList();
            if (menuSonList.size() == 0) {
                continue;
            }


            genMenuJsonTree(jsonObjectSon, menuSonList, from);
        }
    }





	/*@Override
	public Result bindRole_Menu(long roleId, String roleJsonArray, A1OperationlogDto logDto) {
		Result result = new Result();
		A2Role a2Role = a2RoleDao.findById(roleId).get();

		//角色下已存在菜单，先删除这些菜单
		if(a2Role.getA3MenuMyList().size()>0){
			for(A3MenuMy menu1My : a2Role.getA3MenuMyList()){
				a3MenuMyDao.deleteById(menu1My.getId());
			}
		}

		JSONArray jsonArray = new JSONArray(roleJsonArray);
		for(int i=0;i<jsonArray.length();i++){
			JSONObject jsonObject = jsonArray.optJSONObject(i);
			Long menuId = jsonObject.optLong("menuId");
			Long menuParentId = jsonObject.optLong("menuParentId");
			int dataLimitType = jsonObject.optInt("dataLimitType");
			int childrenLength = jsonObject.optInt("childrenLength");
			int type = jsonObject.optInt("type");
			//type=20, 是页面功能button, 只保存这个。上级不能保存，防止加入新button后，页面显示全部是选中状态
			if( (type==10 && childrenLength==0) || type==20) {//子菜单直接打开一个有查询功能的页面，无查询button
				Optional<A3Menu> optionalA3Menu = a3MenuDao.findById(menuId);
				boolean isPresent = optionalA3Menu.isPresent();
				A3Menu a3Menu = optionalA3Menu.get();
				A3MenuMy menuMy = new A3MenuMy().setDefaultValues();
				menuMy.setA2Role(a2Role);
				menuMy.setA3Menu(a3Menu);
				menuMy.setDataLimitType(dataLimitType);
				a3MenuMyDao.save(menuMy);
			}
		}

		//日志
		if(logDto != null){
			logDto.setLogTypeName("后台：员工管理");
			logDto.setDescription("绑定角色 和 菜单：roleId:"+roleId);
			operationlogService.addOperationlog(logDto);
		}
		return result.success();
	}*/

    @Override
    public Result queryMenus4RoleConfByRoleId(long roleId) {
        Result result = new Result();
        JSONArray jsonArr = new JSONArray();
        //取某角色拥有的 菜单
        A2Role a2Role = a2RoleDao.findById(roleId).get();
        List<A3MenuMy> a3MenuMyList = a2Role.getA3MenuMyList();
        for (A3MenuMy menuMy : a3MenuMyList) {
            A3Menu menu = menuMy.getA3Menu();
            long menuId = menu.getId();
            int deleteFlag = menu.getDeleteFlag();
            if (deleteFlag == 1) {
                continue;
            }
            int dataLimitType = menuMy.getDataLimitType();
            JSONObject jo = new JSONObject();
            jo.put("menuId", menuId);
            jo.put("dataLimitType", dataLimitType);
            jsonArr.put(jo);
        }

        String menu4RoleConfByRoleIdJson = jsonArr.toString();
        result.getMap().put("menu4RoleConfByRoleIdJson", menu4RoleConfByRoleIdJson);
        return result.success();
    }

    //[{"text":"系统基本信息管理",'state':'closed',"children":[{"text":"修改密码","attributes":{"url":"user/changePwd.jsp"}},{"text":"修改个人资料","attributes":{"url":"user/changeMyInfo.jsp"}},{"text":"部门管理","attributes":{"url":"user/deptMag.jsp"}},{"text":"后台用户管理","attributes":{"url":"user/userList.jsp"}},{"text":"角色权限配置","attributes":{"url":"user/cfgRoleAuth.jsp"}},{"text":"操作日志查询","attributes":{"url":"log/logList.jsp"}},{"text":"模板页面管理","attributes":{"url":"template/tableList.jsp"}}]},{"text":"客户管理",'state':'closed',"children":[{"text":"个人用户列表","attributes":{"url":"user/customerList.jsp"}}]},{"text":"商户管理",'state':'closed',"children":[{"text":"代理商管理","attributes":{"url":"merchant/merchantAgentList.jsp"}},{"text":"费率管理","attributes":{"url":"merchant/merchantRateList.jsp"}},{"text":"商户增加","attributes":{"url":"merchant/merchantInfoAdd.jsp"}},{"text":"商户列表","attributes":{"url":"merchant/merchantInfoList.jsp"}}]},{"text":"商户平台管理",'state':'closed',"children":[]},{"text":"合作银行管理",'state':'closed',"children":[{"text":"合作银行增加","attributes":{"url":"bankpatcoop/bankPatCoopAdd.jsp"}},{"text":"合作银行列表","attributes":{"url":"bankpatcoop/bankPatCoopList.jsp"}}]},{"text":"退货/取消管理",'state':'closed',"children":[{"text":"退货/取消管理","attributes":{"url":"orderMerReturnMoneyApply/orderMerReturnMoneyApplyList.jsp"}}]},{"text":"网关订单管理",'state':'closed',"children":[{"text":"商品订单列表","attributes":{"url":"order/orderProductList.jsp"}},{"text":"支付订单列表","attributes":{"url":"order/orderPayList.jsp"}},{"text":"银行订单列表","attributes":{"url":"order/orderBankList.jsp"}}]},{"text":"财务结算",'state':'closed',"children":[{"text":"商户结算列表","attributes":{"url":"finacial/finacialOrderProductList.jsp"}},{"text":"银行对账列表","attributes":{"url":"finacial/finacialOrderPayList.jsp"}},{"text":"账户余额统计","attributes":{"url":"template/templateList.jsp?keyRandom=20150423144439356"}},{"text":"汇总表","attributes":{"url":"template/templateList.jsp?keyRandom=20150423145252903"}},{"text":"收单商户运营明细表","attributes":{"url":"template/templateList.jsp?keyRandom=20150423145707996"}},{"text":"商户结算单","attributes":{"url":"template/templateList.jsp?keyRandom=20150423145934153"}},{"text":"银行对账单","attributes":{"url":"template/templateList.jsp?keyRandom=20150423150511418"}}]},{"text":"划款处理",'state':'closed',"children":[]},{"text":"自营产品订单管理",'state':'closed',"children":[{"text":"自营产品订单列表","attributes":{"url":"order/orderProductMyList.jsp"}},{"text":"手机充值订单列表","attributes":{"url":"mobile/mobileInfoList.jsp"}},{"text":"油卡充值订单列表","attributes":{"url":"oilCard/oilCardInfoList.jsp"}}]},{"text":"自营产品通道管理",'state':'closed',"children":[{"text":"手机充值通道管理","attributes":{"url":"channel/mobileChannelChange.jsp"}}]},{"text":"test订单管理",'state':'closed',"children":[]},{"text":"弘康管理",'state':'closed',"children":[]},{"text":"风控管理",'state':'closed',"children":[{"text":"风控规则管理","attributes":{"url":"systemMag/systemMag_queryRiskRule"}},{"text":"风控黑名单","attributes":{"url":"systemMag/riskBlackList.jsp"}},{"text":"风控记录列表","attributes":{"url":"systemMag/riskPayOrderList.jsp"}}]},{"text":"退出系统",'state':'closed',"children":[{"text":"退出","attributes":{"url":"logout"}}]}]

    /**
     * 通过userId查菜单结构（一般首页菜单使用）
     *
     * @param userId
     * @return
     */
    @Override
    public Result queryMenusByUser(long userId) {
        System.out.println("t1:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));
        Result result = new Result();
        A2User user = a2UserDao.findById(userId).get();
        List<A2Role> roleList = user.getA2RoleList();

        //当前用户拥有的所有菜单
        List<Long> menuIdList = new ArrayList();
        for (A2Role role : roleList) {
            for (A3MenuMy menuMy : role.getA3MenuMyList()) {
                Long id = Long.parseLong(menuMy.getA3menuId().toString());
                if (!menuIdList.contains(id)) {
                    menuIdList.add(id);
                }
                //menuIdList.add();
				/*A3Menu menu = menuMy.getA3Menu();
				if(menu.getDeleteFlag() == 1){continue;} // 20200914
				//将所有menu的parentMenu放入myMenuList中
				genParentMenu(menu,myMenuList);
				if(myMenuList.contains(menu)){continue;}
				myMenuList.add(menu);*/
            }
        }
        if (menuIdList.size()==0) {
            return result.fault("未分配角色");
        }
        StringBuilder menuIds = new StringBuilder();
        menuIds.append("(");
        for (Long menuId : menuIdList) {
            menuIds.append(menuId).append(",");
        }
        menuIds.deleteCharAt(menuIds.length() - 1);
        menuIds.append(")");
        String hql = "From A3Menu where deleteflag=0 and id in " + menuIds;
        List<A3Menu> menuList = getCurrentSession().createQuery(hql).list();

        List<A3Menu> myMenuListTmp = new ArrayList<>();
        genParentMenu(menuList, myMenuListTmp);
        System.out.println("t2:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));

        List<A3Menu> myMenuList = myMenuListTmp.stream().distinct().collect(Collectors.toList());

        //排序
        Collections.sort(myMenuList, new Comparator<A3Menu>() {
            @Override
            public int compare(A3Menu o1, A3Menu o2) {
                return o1.getSort() - o2.getSort();
            }
        });

        //找第一级ParentMenu
        List<A3Menu> myMenuParentList = new ArrayList<>();
        for (A3Menu menu : myMenuList) {
            if (menu.getA3MenuParent() == null) {
                myMenuParentList.add(menu);
            }
        }

        System.out.println("t3:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));

        //递归生成树，存储在jsonObject里
        JSONObject jsonObject = new JSONObject();
        genMenuJsonTreeByUser(jsonObject, myMenuParentList, myMenuList);
        JSONArray jsonArray = jsonObject.getJSONArray("children");
        List list = jsonArray.toList();
        result.setList(list);
        System.out.println("t4:" + DateTool.getCurrentDateStr1("yyyy-MM-dd HH:mm:ss.SSS"));
        System.out.println("list:" + list);

        return result.success();
    }

    // 将所有menu的parentMenu放入myMenuList中
    private void genParentMenu(List<A3Menu> menuList, List<A3Menu> myMenuList) {
        // 所有菜单的上一级，批量查询
        List<Long> menuParentIdList = new ArrayList<>();
        for (A3Menu menu : menuList) {
            Long menuParentId = menu.getA3MenuParentId();
            if (menuParentId == null || menuParentId == 0) {
                continue;
            }
            menuParentIdList.add(menuParentId);
        }
        if (menuParentIdList.size() == 0) {
            return;
        }
        StringBuilder menuParentIds = new StringBuilder();
        menuParentIds.append("(");
        for (Long menuId : menuParentIdList) {
            menuParentIds.append(menuId).append(",");
        }
        menuParentIds.deleteCharAt(menuParentIds.length() - 1);
        menuParentIds.append(")");
        String hql = "From A3Menu where deleteflag=0 and id in " + menuParentIds;
        List<A3Menu> menuParentList = getCurrentSession().createQuery(hql).list();

        // A3Menu menuParent = menu.getA3MenuParent();
        // menu.setA3MenuParentTmp(menuParent);

        if (menuParentList == null || menuParentList.size() == 0) {
            return;
        }
        myMenuList.addAll(menuParentList);

        genParentMenu(menuParentList, myMenuList);
    }
	/*private void genParentMenu(A3Menu  menu, List<A3Menu> myMenuTopList){
		A3Menu menuParent = menu.getA3MenuParent();
		// menu.setA3MenuParentTmp(menuParent);

		if(menuParent==null)return;
		if(!myMenuList.contains(menuParent)){
			myMenuList.add(menuParent);
		}
		genParentMenu(menuParent, myMenuList);
	}*/

    /**
     * 递归Menu生成树
     *
     * @param jsonObject:当前用户拥有的所有菜单      转换成json模式
     * @param myMenuParentList：传入的上一级菜单列表
     * @param myMenuList:当前用户拥有的所有菜单
     */
    private void genMenuJsonTreeByUser(JSONObject jsonObject, List<A3Menu> myMenuParentList, List<A3Menu> myMenuList) {
        JSONArray jsonArray = new JSONArray();
        jsonObject.put("children", jsonArray);

        for (A3Menu menu : myMenuParentList) {
            long id = menu.getId();
            long menuParentId = 0;
            if (menu.getA3MenuParent() != null) {
                menuParentId = menu.getA3MenuParent().getId();
            }
            int deleteFlag = menu.getDeleteFlag();
            if (deleteFlag == 1) {
                continue;
            }
            String text = menu.getText();
            String auth = menu.getAuth();
            if (!StringUtils.isNull(auth)) {
                continue;
            } //去权限menu
            String url = menu.getUrl();
            int type = menu.getType();
            int hasDataLimit = menu.getHasDataLimit();
            String iconClass = menu.getIconClass();
            int sort = menu.getSort();
            String nameEn = menu.getNameEn() == null ? "" : menu.getNameEn();

            //json
            JSONObject jsonObjectSon = new JSONObject();
            jsonObjectSon.put("id", id);
            jsonObjectSon.put("menuParentId", menuParentId);
            jsonObjectSon.put("text", text);
            jsonObjectSon.put("name", text);
            jsonObjectSon.put("nameEn", nameEn);
            jsonObjectSon.put("url", url == null ? "" : url);
            jsonObjectSon.put("type", type);
            jsonObjectSon.put("iconClass", iconClass);
            jsonObjectSon.put("hasDataLimit", hasDataLimit);
            jsonObjectSon.put("sort", sort);
            jsonArray.put(jsonObjectSon);

            //取当前menu的下级menu
            List<A3Menu> menuSonList = new ArrayList<>();
            for (A3Menu menu1 : myMenuList) {
                if (menu1.getA3MenuParent() != null && menu1.getA3MenuParent().getId() == menu.getId()) {
                    menuSonList.add(menu1);
                }
            }

            if (menuSonList.size() == 0) {
                continue;
            }
            // if(type >= 10){continue;}
            genMenuJsonTreeByUser(jsonObjectSon, menuSonList, myMenuList);
        }
    }


    /**
     * 权限管理，通过url查所有权限列表
     *
     * @param url
     * @return
     */
    @Override
    public Set<String> getMenu2AuthListByUrl(String url) {
        Set<String> menuAuthList = new HashSet<>();
        A3Menu a3Menu = new A3Menu();
        a3Menu.setUrl(url);
        List<A3Menu> menuList = a3MenuDao.findAll(Example.of(a3Menu));
        for (A3Menu menu : menuList) {
            menuAuthList.add(String.valueOf(menu.getId()));
        }
        return menuAuthList;
    }


    private static Dto getDtoAnnotation(final Class<?> dto)
            throws AnnotationMissingAutobindingException {
        final Dto ann = dto.getAnnotation(Dto.class);
        if (ann == null || ann.value() == null || ann.value().length() == 0) {
            throw new AnnotationMissingAutobindingException(dto.getCanonicalName());
        }
        return ann;
    }

    private static Class detectAutobinding(final Class<?> dto, final Dto ann)
            throws AutobindingClassNotFoundException {
        try {
            return Class.forName(ann.value());
        } catch (ClassNotFoundException cnfe) {
            throw new AutobindingClassNotFoundException(dto.getCanonicalName(), ann.value());
        }
    }

    /**
     * 权限管理，登录时调用
     *
     * @param loginname
     * @return
     */
    @Override
    public A2UserDto getUserByLoginname(String loginname) {
        A2UserDto userDto = new A2UserDto();

        A2User a2User = new A2User();
        a2User.setLoginName(loginname);
        a2User.setDeleteFlag(0);
        if (a2UserDao.count(Example.of(a2User))!=1){
            return null;
        }
        Optional<A2User> optionalA2User = a2UserDao.findOne(Example.of(a2User));
        if (!optionalA2User.isPresent()) {
            return null;
        }
        A2User user = optionalA2User.get();
        if (StringUtils.isNull(user.getPasswordBcrypt())) return null;
        A2Dept a2Dept = user.getA2Dept();
        if (a2Dept==null) return null;
        A2Dept a2DeptPost = user.getA2DeptPost();
        if (a2DeptPost==null) return null;
        List roleList = user.getA2RoleList();
        if (roleList==null || roleList.isEmpty()) return null;

        try {
            PropertyUtils.copyProperties(userDto, user);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //
        userDto.setInstituteId(a2Dept.getId());
        userDto.setInstituteCode(a2Dept.getNumber());
        userDto.setInstituteName(a2Dept.getName());
        userDto.setDepartmentId(a2DeptPost.getId());
        userDto.setDepartmentCode(a2DeptPost.getNumber());
        userDto.setDepartmentName(a2DeptPost.getName());


        userDto.setCreateDateStr(DateUtils.timestamp2String(user.getCreateDate()));


        // List<Long> menuIdList = new ArrayList<>();
        Map<String, Integer> dateLimitTypeMap = new HashMap<>();
        //取用户权限列表
        for (A2Role role : user.getA2RoleList()) {
            for (A3MenuMy menuMy : role.getA3MenuMyList()) {
                // Integer menuId = menuMy.getA3menuId();
                // menuIdList.add(Long.parseLong(menuId.toString()));
                // 数据访问边界 0: 全部， 10: 部门内部
                int dataLimitType = menuMy.getDataLimitType();
                A3Menu menu = menuMy.getA3Menu();
                String auth = menu.getAuth();
                if (!StringUtils.isNull(auth)) {
                    auth = auth.replaceAll("\n","");
                    // if auth = dept:query;dept:add;user:query;
                    if (auth.contains(";")) {
                        List<String> authList = Arrays.asList(auth.split(";"));
                        for (String _auth : authList) {
                            if (!StringUtils.isNull(_auth)) {
                                _auth = _auth.trim();
                                if (dataLimitType != 0) {
                                    // key重名时，取用dataLimitType数值大的，权限更小
                                    Object _dt = userDto.getDataLimitMap().get(_auth);
                                    if (com.rt.easyjava.common.utils.others.StringUtils.isNull(_dt)) {
                                        userDto.getDataLimitMap().put(_auth, dataLimitType);
                                    } else {
                                        int _dtInt = Integer.parseInt(_dt.toString());
                                        if (dataLimitType > _dtInt) {
                                            userDto.getDataLimitMap().put(_auth, dataLimitType);
                                        }
                                    }
                                }
                                if (userDto.getMenu2AuthList().contains(_auth)) {
                                    continue;
                                }
                                userDto.getMenu2AuthList().add(_auth);
                            }
                        }
                    } else {
                        if (dataLimitType != 0) {
                            // key重名时，取用dataLimitType数值大的，权限更小
                            Object _dt = userDto.getDataLimitMap().get(auth);
                            if (com.rt.easyjava.common.utils.others.StringUtils.isNull(_dt)) {
                                userDto.getDataLimitMap().put(auth, dataLimitType);
                            } else {
                                int _dtInt = Integer.parseInt(_dt.toString());
                                if (dataLimitType > _dtInt) {
                                    userDto.getDataLimitMap().put(auth, dataLimitType);
                                }
                            }
                        }
                        if (userDto.getMenu2AuthList().contains(auth)) {
                            continue;
                        }
                        userDto.getMenu2AuthList().add(auth);
                    }
                }
                //页面功能点，如：查询; role-menu link table 中存储的type是20=function
                /*for(A3Menu menu1 : menu.getA3MenuSonList()){
                    if(!StringUtils.isNull(menu1.getAuth())) {
                        userDto.getMenu2AuthList().add(menu1.getAuth());
                    }
                }*/
                //genParentMenuUrl(menu,userDto);
            }
        }
        // 提高系统运行速度
		/*System.out.println("menuIdList: " +menuIdList);
        List<A3Menu> menuList = a3MenuDao.findAllById(menuIdList);
        for (A3Menu menu: menuList) {
			// int dataLimitType = menuMy.getDataLimitType();
			if(!StringUtils.isNull(menu.getAuth())) {
				if (userDto.getMenu2AuthList().contains(menu.getAuth())) {
					continue;
				}
				userDto.getMenu2AuthList().add(menu.getAuth());
			}
		}
        userDto.setA2RoleList(null);*/
        userDto.setA2RoleList(null);

        return userDto;
    }

    private void genParentMenuUrl(A3Menu menu, A2UserDto userDto) {
        A3Menu parentMenu = menu.getA3MenuParent();
        if (parentMenu == null) {
            return;
        }
        if (!org.apache.commons.lang.StringUtils.isBlank(parentMenu.getAuth())) {
            userDto.getMenu2AuthList().add(parentMenu.getAuth());
        }
        genParentMenuUrl(parentMenu, userDto);
    }


    @Resource
    private TmptUserSettingMapper tmptUserSettingMapper;


    /**
     * 源码模式生成二级菜单
     *
     * @param paramMap long _templateTableId = (Long)paramMap.get("_templateTableId");
     *                 long menuIdParent = (Long)paramMap.get("menuIdParent");
     *                 String menuName = (String)paramMap.get("menuName");
     *                 long userId = (Long)paramMap.get("userId");
     * @return
     */
    @Override
    public Result template2menuSourceCode(Map<String, Object> paramMap) {
        long _templateTableId = (Long) paramMap.get("_templateTableId");
        long menuIdParent = (Long) paramMap.get("menuIdParent");
        String moduleName = (String) paramMap.get("moduleName");
        String domainName = (String) paramMap.get("domainName");
        String stripPrefix = (String) paramMap.get("stripPrefix"); // 表前缀
        if (stripPrefix==null) stripPrefix = "";
        String menuName = (String) paramMap.get("menuName");
        long userId = Long.parseLong(paramMap.get("userId").toString());
        // String module = getCurrentModule(userId);


        Result result = new Result();
        //取模板表
        A1TemplateTable table = a1TemplateTableDao.findById(_templateTableId).get();
        //
        String versionJoStr = table.getVersion();
        String module = moduleName;
        String domain = domainName;
        if (!StringUtils.isNull(versionJoStr)) {
            try {
                com.alibaba.fastjson.JSONObject versionJo = com.alibaba.fastjson.JSONObject.parseObject(versionJoStr);
                module = versionJo.getString("module");
                domain = versionJo.getString("domain");
                stripPrefix = versionJo.getString("stripPrefix");
            }catch (Exception e){}
        }
        String modulePath = module+"/"+domain;


        String tableNameShow = table.getTableNameShow();
        String keyRandom = table.getKeyRandom();
        String tableName = table.getTableName();
        String tableNameStripPrefix = tableName.replaceFirst(stripPrefix,"");
        String tableNameProperty = FmUtils.switch2Property(tableNameStripPrefix);
        String className = FmUtils.firstWord2Upper(tableNameProperty);
        String classInstance = FmUtils.firstWord2Lower(tableNameProperty);

        //menu2Name
        menuName = StringUtils.isNull(menuName) ? tableNameShow : menuName;



        Result result1 = checkMenuName(menuName);
        if (!result1.isSuccess()) {
            return result1;
        }

        //取一级菜单
        A3Menu menuParent = a3MenuDao.findById(menuIdParent).get();

        //生成二级菜单
        A3Menu menu2 = genMenu(module, menuName, className + "-ComplexList-backup", "coding/" + modulePath + "/" + classInstance + "/complex-list", classInstance, userId, table.getKeyRandom(), menuParent, false);
        //生成三级菜单 （模板）
        // config json
        String cfgJsonStr = table.getTreeJson();
        Map<String, Object> configMap = FmUtils.parseConfigJson(cfgJsonStr, "");
        // tree
        Boolean isTreeTable = (Boolean) configMap.get("isTreeTable");
        // One to Many
        // Boolean hasO2M = (Boolean)configMap.get("hasO2M");
        List<Map> o2mList = (List<Map>) configMap.get("o2mList");
        // hasAsideTree
        Boolean hasAsideTree = (Boolean) configMap.get("hasAsideTree");
        //
        genMenu(module, "FormAdd", className + "-FormAdd", "coding/" + modulePath + "/" + classInstance + "/form-add", classInstance, userId, table.getKeyRandom(), menu2, true);
        genMenu(module, "List", className + "-List", "coding/" + modulePath + "/" + classInstance + "/list", classInstance, userId, table.getKeyRandom(), menu2, true);
        genMenu(module, "ListLineEdit", className + "-ListLineEdit", "coding/" + modulePath + "/" + classInstance + "/list-line-edit", classInstance, userId, table.getKeyRandom(), menu2, true);
        genMenu(module, "ComplexList", className + "-ComplexList", "coding/" + modulePath + "/" + classInstance + "/complex-list", classInstance, userId, table.getKeyRandom(), menu2, true);
        genMenu(module, "ComplexListLE", className + "-ComplexListLE", "coding/" + modulePath + "/" + classInstance + "/complex-list-line-edit", classInstance, userId, table.getKeyRandom(), menu2, true);
        genMenu(module, "AsideCalendar", className + "-AsideCalendar", "coding/" + modulePath + "/" + classInstance + "/aside-calendar", classInstance, userId, table.getKeyRandom(), menu2, true);
        for (Map o2mMap : o2mList) {
            Boolean hasO2M = (Boolean) o2mMap.get("hasO2M");
            String classNameO2M = (String) o2mMap.get("classNameO2M");
            if (hasO2M) {
                genMenu(module, "AsideO2M-" + classNameO2M, className + "-AsideO2M-" + classNameO2M, "coding/" + modulePath + "/" + classInstance + "/aside-o2m-" + classNameO2M, classInstance, userId, table.getKeyRandom(), menu2, true);
            }
        }
        if (isTreeTable) {
            genMenu(module, "Tree", className + "-Tree", "coding/" + modulePath + "/" + classInstance + "/tree", classInstance, userId, table.getKeyRandom(), menu2, true);
            genMenu(module, "TreeTable", className + "-TreeTable", "coding/" + modulePath + "/" + classInstance + "/tree-table", classInstance, userId, table.getKeyRandom(), menu2, true);
        }
        if (hasAsideTree) {
            genMenu(module, "AsideTree", className + "-AsideTree", "coding/" + modulePath + "/" + classInstance + "/aside-tree", classInstance, userId, table.getKeyRandom(), menu2, true);
        }

        return result.success();
    }

    private A3Menu genMenu(String module, String text, String nameEn, String url, String tableNameProperty, Long userId, String keyRandom, A3Menu menuParent, boolean hasAuth) {
        A3Menu menu = new A3Menu().setDefaultValues();
        menu.setText(text);
        menu.setNameEn(nameEn);
        menu.setUrl(url);
        menu.setA3MenuParent(menuParent);
        menu.setType(10);//0=menu; 10=leave menu; 20=function 30=function url
        menu.setKeyRandom(keyRandom);
        menu = a3MenuDao.save(menu);
        //在指定菜单下生成权限
        if (hasAuth) {
            genAuth(module, tableNameProperty, userId, menu);
        }
        return menu;
    }

    /**
     * 在指定菜单下生成权限
     *
     * @param tableNameProperty
     * @param userId
     * @param menu
     */
    private void genAuth(String module, String tableNameProperty, Long userId, A3Menu menu) {
        A3Menu funQuery = new A3Menu().setDefaultValues();
        funQuery.setText("查询");
        funQuery.setAuth(module+":"+tableNameProperty + ":query");
        funQuery.setType(20);
        funQuery.setA3MenuParent(menu);
        funQuery = a3MenuDao.save(funQuery);
        //当前用户直接授权
        setMenu2Role(userId, funQuery);
        //生成添加的资源
        A3Menu funAdd = new A3Menu().setDefaultValues();
        funAdd.setText("添加");
        funAdd.setAuth(module+":"+tableNameProperty + ":create");
        funAdd.setType(20);
        funAdd.setA3MenuParent(menu);
        funAdd = a3MenuDao.save(funAdd);
        //当前用户直接授权
        setMenu2Role(userId, funAdd);
        //生成修改的资源
        A3Menu funEdit = new A3Menu().setDefaultValues();
        funEdit.setText("修改");
        funEdit.setAuth(module+":"+tableNameProperty + ":update");
        funEdit.setType(20);
        funEdit.setA3MenuParent(menu);
        funEdit = a3MenuDao.save(funEdit);
        //当前用户直接授权
        setMenu2Role(userId, funEdit);
        //生成删除的资源
        A3Menu funRemove = new A3Menu().setDefaultValues();
        funRemove.setText("删除");
        funRemove.setAuth(module+":"+tableNameProperty + ":delete");
        funRemove.setType(20);
        funRemove.setA3MenuParent(menu);
        funRemove = a3MenuDao.save(funRemove);
        //当前用户直接授权
        setMenu2Role(userId, funRemove);
        //生成下载报表的资源
        A3Menu funReport = new A3Menu().setDefaultValues();
        funReport.setText("报表");
        funReport.setAuth(module+":"+tableNameProperty + ":report");
        funReport.setType(20);
        funReport.setA3MenuParent(menu);
        funReport = a3MenuDao.save(funReport);
        //当前用户直接授权
        setMenu2Role(userId, funReport);

    }

    /**
     * 存在就删除
     * backup:重名，就备份原菜单名
     *
     * @param menuName
     * @return
     */
    private Result checkMenuName(String menuName) {
        Result result = new Result();
        A3Menu a3Menu = new A3Menu();
        a3Menu.setText(menuName);
        a3Menu.setDeleteFlag(0);
        List<A3Menu> menuList = a3MenuDao.findAll(Example.of(a3Menu));
        for (A3Menu menu : menuList) {
            menu.setText(menuName + "___" + menu.getId());
            menu.setDeleteFlag(1); // 备份下删除掉
            a3MenuDao.save(menu);
        }
		/*long count = a3MenuDao.count(Example.of(a3Menu));
		if(count > 0){
			return result.fault("已存在二级菜单，可删除原菜单后继续，或修改菜单名称："+menuName);
		}*/
        return result.success();
    }

    /**
     * 当前用户直接授权
     *
     * @return
     */
    private boolean setMenu2Role(long userId, A3Menu menu) {
        A2User user = a2UserDao.findById(userId).get();
        A2Role a2Role = user.getA2RoleList().get(0);
        A3MenuMy menuMy = new A3MenuMy().setDefaultValues();
        menuMy.setA2Role(a2Role);
        menuMy.setA3Menu(menu);
        menuMy.setDataLimitType(0);
        a3MenuMyDao.save(menuMy);
        return true;
    }

    /**
     * 生成模板菜单
     *
     * @param paramMap long _templateTableId = (Long)paramMap.get("_templateTableId");
     *                 long menuIdParent = (Long)paramMap.get("menuIdParent");
     *                 String menuName = (String)paramMap.get("menuName");
     *                 long userId = (Long)paramMap.get("userId");
     * @return
     */
    @Override
    public Result template2menu(Map<String, Object> paramMap) {
        long _templateTableId = (Long) paramMap.get("_templateTableId");
        long menuIdParent = (Long) paramMap.get("menuIdParent");
        String menuName = (String) paramMap.get("menuName");
        long userId = Long.parseLong(paramMap.get("userId").toString());

        Result result = new Result();
        //取模板表
        A1TemplateTable table = a1TemplateTableDao.findById(_templateTableId).get();
        String tableNameShow = table.getTableNameShow();
        String keyRandom = table.getKeyRandom();
        String tableName = table.getTableName();
        String tableNameProperty = FmUtils.switch2Property(tableName);

        //menu2Name
        menuName = StringUtils.isNull(menuName) ? tableNameShow : menuName;

        // 存在则修改一下，原菜单名称
        Result result1 = checkMenuName(menuName);
        if (!result1.isSuccess()) {
            return result1;
        }

        //取一级菜单
        A3Menu menuParent = a3MenuDao.findById(menuIdParent).get();
        //生成二级菜单
        A3Menu menu = new A3Menu().setDefaultValues();
        menu.setText(menuName);
        menu.setA3MenuParent(menuParent);
        menu.setUrl(keyRandom);
        menu.setNameEn("tmpt-preview");
        menu.setType(10);//0=menu; 10=leave menu; 20=function 30=function url
        menu = a3MenuDao.save(menu);
        //生成功能权限
        A3Menu funQuery = new A3Menu().setDefaultValues();
        funQuery.setText("查询");
        funQuery.setAuth(tableNameProperty + "_:query");
        funQuery.setType(20);
        funQuery.setA3MenuParent(menu);
        funQuery = a3MenuDao.save(funQuery);
        //当前用户直接授权
        setMenu2Role(userId, funQuery);

        //生成添加的权限
        A3Menu funAdd = new A3Menu().setDefaultValues();
        funAdd.setText("添加/修改");
        funAdd.setAuth(tableNameProperty + "_:createUpdate");
        funAdd.setType(20);
        funAdd.setA3MenuParent(menu);
        funAdd = a3MenuDao.save(funAdd);
        //当前用户直接授权
        setMenu2Role(userId, funAdd);
        //生成删除的权限
        A3Menu funRemove = new A3Menu().setDefaultValues();
        funRemove.setText("删除");
        funRemove.setAuth(tableNameProperty + "_:delete");
        funRemove.setType(20);
        funRemove.setA3MenuParent(menu);
        funRemove = a3MenuDao.save(funRemove);
        //当前用户直接授权
        setMenu2Role(userId, funRemove);
        //生成下载报名的权限
        A3Menu funReport = new A3Menu().setDefaultValues();
        funReport.setText("报表");
        funReport.setAuth(tableNameProperty + "_:report");
        funReport.setType(20);
        funReport.setA3MenuParent(menu);
        funReport = a3MenuDao.save(funReport);
        //当前用户直接授权
        setMenu2Role(userId, funReport);


        return result.success();
    }

    @Override
    public Result changeMenuToMenu1(long id_change_position, long menu1_id_change_position) {
        Result result = new Result();
        A3Menu menu1 = a3MenuDao.findById(menu1_id_change_position).get();
        A3Menu menu2 = a3MenuDao.findById(id_change_position).get();
        menu2.setA3MenuParent(menu1);
        a3MenuDao.save(menu2);
        return result.success();
    }


    @Override
    public Result olap2menu(Map<String, Object> paramMap) {
        long menuIdParent = (Long) paramMap.get("menuIdParent");
        String menuName = (String) paramMap.get("menuName");
        String menuUrl = (String) paramMap.get("menuUrl");
        String menuUrlFun = (String) paramMap.get("menuUrlFun");
        //当前用户直接授权
        long userId = (Long) paramMap.get("userId");

        Result result = new Result();

        Result result1 = checkMenuName(menuName);
        if (!result1.isSuccess()) {
            return result1;
        }

        //取一级菜单
        A3Menu menuParent = a3MenuDao.findById(menuIdParent).get();
        //生成二级菜单
        A3Menu menu = new A3Menu();
        menu.setText(menuName);
        menu.setA3MenuParent(menuParent);
        menu.setUrl(menuUrl);
        menu.setType(10);//0=menu; 10=leave menu; 20=function 30=function url
        a3MenuDao.save(menu);
        //当前用户直接授权
        //setMenu2Role(userId, menu);

        //生成功能资源
        A3Menu funQuery = new A3Menu();
        funQuery.setUrl(menuUrlFun);
        funQuery.setText("查询");
        funQuery.setType(20);
        funQuery.setA3MenuParent(menu);
        a3MenuDao.save(funQuery);
        //当前用户直接授权
        setMenu2Role(userId, funQuery);


        return result.success();
    }

}

